home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / basic / vbmake.exe / MM.BAS < prev    next >
Encoding:
BASIC Source File  |  1993-05-05  |  19.3 KB  |  627 lines

  1. ' Billy Dennigan MBN International Systems Ltd          March 1993
  2. ' Compuserve ID 100014,2700
  3. ' Makefile Generator
  4. ' This program generates a simple makefile by copying the MS Basic .MAK file
  5. ' to a file usable by the NMAKE utility, with the appropriate dependencies
  6. ' and switches.
  7. ' If you find this program useful, please acknowledge by E-Mail
  8. ' Example .INI files are included for VBDOS and BC7
  9. ' These should be changed to suit your personal configuration
  10. ' MM /? for help
  11.  
  12. DECLARE SUB IncludeFiles (Filename$, OutFile%)
  13. DECLARE SUB LoadList (ListFile$, ObjList$(), NumObjs%)
  14. DECLARE SUB ReadIni (IniFile$, Options() AS ANY)
  15. DECLARE SUB ShowHelp ()
  16. DECLARE SUB Substitute (Change$, ObjList$())
  17. DECLARE FUNCTION CmdParam$ (Cmd$, name$)
  18. DECLARE FUNCTION GetValue$ (Num%, Ini() AS ANY)
  19. DECLARE FUNCTION RemoveExt$ (Filename$)
  20. DECLARE FUNCTION RemovePath$ (Filename$)
  21.  
  22. '============== one of these per entry in the .INI file ==============
  23. TYPE IniRec
  24.   Index AS INTEGER
  25.   Value AS STRING * 50
  26. END TYPE
  27.  
  28. CONST FALSE = 0, TRUE = NOT FALSE
  29. CONST NumOfSources = 128  ' max. number of sources for an EXE file
  30. CONST MaxIniLines = 128   ' max. number of entries in .INI file
  31. CONST NumSettings = 8     ' change this if you add any settings to DATA
  32.  
  33. REDIM ObjList$(NumOfSources)
  34. REDIM Inis(MaxIniLines) AS IniRec
  35.    
  36. PRINT
  37. PRINT "     Makefile Generator.    Version 2.0   Mar.1993"
  38. PRINT "     Billy Dennigan, MBN International Systems Ltd."
  39. PRINT
  40.  
  41. Cmd$ = COMMAND$
  42.  
  43. '========== HELP FACILITY ==========
  44. IF INSTR(Cmd$, "/?") THEN
  45.   CALL ShowHelp
  46.   END
  47. END IF
  48.  
  49. '========= get the target filename if necessary ============
  50. IF Cmd$ = "" THEN
  51.   PRINT "Target File :";
  52.   INPUT TargetFile$
  53. ELSE
  54.   TargetFile$ = Cmd$
  55. END IF
  56. IF LEN(TargetFile$) = 0 THEN END
  57.  
  58. '================ GET THE NAME OF THE .INI FILE ===================
  59. IniFile$ = "MM.INI"
  60. DO UNTIL LEN(DIR$(IniFile$))
  61.   PRINT "Cannot find MM Initialisation file "; IniFile$;
  62.   PRINT " Please enter new file spec: ";
  63.   INPUT IniFile$
  64.   IF LEN(IniFile$) = 0 THEN CLOSE : END
  65. LOOP
  66.  
  67. '============ LOAD DATA INTO ARRAY OF RECORDS inis() ==============
  68. CALL ReadIni(IniFile$, Inis())
  69.  
  70. 'truncate the extension from the target file if it was specified
  71. TargetFile$ = UCASE$(TargetFile$)
  72. TargetFile$ = RemoveExt$(TargetFile$)
  73.  
  74. MakeFile$ = TargetFile$                  ' Makefile to be generated
  75. RespFile$ = TargetFile$ + ".LNK"         ' response file for linker
  76. ListFile$ = TargetFile$ + ".MAK"         ' input list of required files
  77. Tab$ = CHR$(9)
  78.  
  79. '--- load in the list of Modules -----
  80. CALL LoadList(ListFile$, ObjList$(), NumObjs%)
  81.   
  82. MkeFile% = FREEFILE
  83. OPEN MakeFile$ FOR OUTPUT AS #MkeFile%         ' MakeFile
  84. LnkFile% = FREEFILE
  85. OPEN RespFile$ FOR OUTPUT AS #LnkFile%         ' Response file
  86. mmddyy$ = DATE$
  87. ddmmyy$ = MID$(DATE$, 4, 2) + "/" + LEFT$(DATE$, 2) + "/" + RIGHT$(DATE$, 2)
  88.  
  89. PRINT #MkeFile%, "# Makefile for "; TargetFile$
  90. PRINT #MkeFile%, "# Date written: "; ddmmyy$; " at "; LEFT$(TIME$, 5);
  91. PRINT #MkeFile%, " by Makefile Generator [MM] Version 1.10"
  92. PRINT #MkeFile%, "# .INI file used was "; IniFile$
  93. PRINT #MkeFile%, "# Billy Dennigan, MBN International Systems Ltd."
  94. PRINT #MkeFile%, "# Uses response file "; RespFile$; " for Linker"
  95. PRINT #MkeFile%, "#"
  96.  
  97. '------ compiler is Setting 1 -----
  98. DO
  99.   Tmp$ = GetValue$(1, Inis())
  100.   TmpLen% = LEN(Tmp$)
  101.   IF TmpLen% THEN Compiler$ = Tmp$
  102. LOOP WHILE TmpLen%
  103.  
  104. '------ linker is Setting 2 ------
  105. DO
  106.   Tmp$ = GetValue$(2, Inis())
  107.   TmpLen% = LEN(Tmp$)
  108.   IF TmpLen% THEN Linker$ = Tmp$
  109. LOOP WHILE TmpLen%
  110.  
  111. '--------- extract all the compiler flags (Setting 3) ---------
  112. DO
  113.   ThisFlag$ = GetValue$(3, Inis())
  114.   CompFlag$ = CompFlag$ + ThisFlag$
  115. LOOP WHILE LEN(ThisFlag$)
  116.  
  117. '--------- extract all the linker flags (Setting 4) -----------
  118. DO
  119.   ThisFlag$ = GetValue$(4, Inis())
  120.   LinkFlag$ = LinkFlag$ + ThisFlag$
  121. LOOP WHILE LEN(ThisFlag$)
  122.  
  123. '--------- get filename substitutions (Setting 6) ------------
  124. DO
  125.   Change$ = GetValue$(6, Inis())
  126.   IF LEN(Change$) = 0 THEN EXIT DO
  127.   CALL Substitute(Change$, ObjList$())
  128. LOOP
  129.  
  130.  
  131. '------ INCLUDEs is Setting 7 ------
  132. 'At this point, just determine whether or not the user wants INCLUDED files
  133. ' put into the dependencies list. Will process them later on.
  134. DO
  135.   Tmp$ = GetValue$(7, Inis())
  136.   TmpLen% = LEN(Tmp$)
  137.   IF TmpLen% THEN GetIncludes$ = UCASE$(Tmp$)
  138. LOOP WHILE TmpLen%
  139. IF INSTR(GetIncludes$, "TRUE") THEN GetIncludes% = -1
  140.  
  141.  
  142. '------ ObjDir is Setting 8 ------
  143. ' this can be used to specify a directory where all .OBJ files are to be put
  144. DO
  145.   Tmp$ = GetValue$(8, Inis())
  146.   TmpLen% = LEN(Tmp$)
  147.   IF TmpLen% THEN
  148.     ObjDir$ = UCASE$(Tmp$)
  149.     ObjDir% = TRUE
  150.   END IF
  151. LOOP WHILE TmpLen%
  152.  
  153. '----- format the path so that it can be used to make up a valid filename
  154. LastChar$ = RIGHT$(ObjDir$, 1)
  155. IF LastChar$ <> ":" AND LastChar$ <> "\" THEN ObjDir$ = ObjDir$ + "\"
  156.  
  157.  
  158.  
  159. PRINT #MkeFile%, "# Can change your source file and compilers,etc here:"
  160. PRINT #MkeFile%, ""
  161. PRINT #MkeFile%, "EXE = "; TargetFile$
  162. PRINT #MkeFile%, "COMPILE = "; Compiler$
  163. PRINT #MkeFile%, "LINK = "; Linker$
  164. PRINT #MkeFile%, "COMPFLAGS = "; CompFlag$
  165. PRINT #MkeFile%, "LINKFLAGS = "; LinkFlag$
  166. PRINT #MkeFile%,
  167. PRINT #MkeFile%, "ALL : $(EXE).EXE"
  168.  
  169. '=========== DEPENDENCIES FOR THE .OBJ FILE  (COMPILATION PHASE) ===========
  170. FOR i% = 1 TO NumObjs%
  171.   Filename$ = ObjList$(i%)
  172.   Stem$ = RemoveExt$(Filename$)
  173.   
  174.   '---------- If a path was specified for the .OBJ files ---------
  175.   IF ObjDir% THEN Stem$ = ObjDir$ + RemovePath$(Stem$)
  176.  
  177.   PRINT Filename$;
  178.   PRINT #MkeFile%, ""
  179.   PRINT #MkeFile%, Stem$; ".OBJ : ";
  180.   PRINT #MkeFile%, Filename$;
  181.   IF GetIncludes% THEN
  182.     '------ Find which files have been INCLUDEd in this one ------
  183.     Col% = POS(0): Row% = CSRLIN
  184.     COLOR 15
  185.     PRINT " Scanning...";
  186.     COLOR 7
  187.     CALL IncludeFiles(Filename$, MkeFile%)
  188.     LOCATE Row%, Col%: PRINT "            ";
  189.     LOCATE Row%, Col%
  190.   END IF
  191.   PRINT
  192.   
  193.   PRINT #MkeFile%,
  194.   PRINT #MkeFile%, Tab$; "$(COMPILE) $(COMPFLAGS) "; Filename$; " "; Stem$; ".OBJ ;"
  195.   
  196. NEXT i%
  197.  
  198.  
  199. '========== DEPENDENCIES FOR THE .EXE FILE i.e. THE LINK PHASE =============
  200. PRINT #MkeFile%, ""
  201. PRINT #MkeFile%, "$(EXE).EXE : ";
  202. FOR i% = 1 TO NumObjs%
  203.   ObjFile$ = RemoveExt$(ObjList$(i%)) + ".OBJ "
  204.  
  205.   IF ObjDir% THEN ObjFile$ = ObjDir$ + RemovePath$(ObjFile$)
  206.  
  207.   PRINT #MkeFile%, ObjFile$; " ";
  208. NEXT i%
  209.  
  210. '=============== THE .EXE IS ALSO DEPENDENT ON .LIB FILES ==================
  211. Lib$ = GetValue$(0, Inis())     ' reset internal pointers
  212. DO
  213.   Lib$ = GetValue$(5, Inis())
  214.   IF LEN(Lib$) THEN PRINT #MkeFile%, UCASE$(Lib$); " ";  ELSE EXIT DO
  215. LOOP
  216.  
  217. PRINT #MkeFile%, ""
  218.  
  219. PRINT #MkeFile%, Tab$; "$(LINK) $(LINKFLAGS) ";
  220. PRINT #MkeFile%, "@"; RespFile$
  221.  
  222.  
  223. '=============== GENERATE THE LINKER RESPONSE FILE ===================
  224. '--------------- DEAL WITH ALL NECESSARY .OBJ FILES ------------------
  225. FOR i% = 1 TO NumObjs%
  226.   ObjFile$ = RemoveExt$(ObjList$(i%)) + ".OBJ "
  227.  
  228.   '--- temporary: leave the OBJ files in current dir ----
  229.   IF ObjDir% THEN ObjFile$ = ObjDir$ + RemovePath$(ObjFile$)
  230.   
  231.   PRINT #LnkFile%, ObjFile$; " +"
  232. NEXT i%
  233. '--------------- TERMINATE THE LIST OF .OBJ FILES ---------------------
  234. PRINT #LnkFile%,
  235.  
  236. '--------------- SPECIFY THE NAME OF THE .EXE FILE --------------------
  237. PRINT #LnkFile%, TargetFile$; ".EXE"
  238.  
  239. '--------------- SPECIFY THE NAME OF THE .MAP FILE --------------------
  240. PRINT #LnkFile%, "NUL.MAP"
  241.  
  242. '--------------- GENERATE THE LIST OF LIBRARY FILES -------------------
  243. Lib$ = GetValue$(0, Inis())     ' reset internal pointers
  244. DO
  245.   PRINT "Libraries : ";
  246.   Lib$ = GetValue$(5, Inis())
  247.  
  248.   'when "LIB=;" is encountered, no more libraries are included.
  249.   SemiColon% = INSTR(Lib$, ";")
  250.   IF SemiColon% THEN
  251.     Lib$ = LEFT$(Lib$, SemiColon%)
  252.     IF Lib$ = ";" THEN PRINT : EXIT DO
  253.   END IF
  254.  
  255.   IF LEN(Lib$) = 0 THEN         ' if the .INI file has no more libs,
  256.     INPUT "", Lib$              ' then get one from the user
  257.   ELSE
  258.     PRINT Lib$; "+"             ' this is the lib read from the .INI file
  259.   END IF
  260.   IF LEN(Lib$) = 0 THEN EXIT DO
  261.  
  262.   PRINT #LnkFile%, UCASE$(Lib$); "+"
  263. LOOP
  264.  
  265. '--------------- TERMINATE THE LIST OF .LIB FILES ---------------------
  266. PRINT #LnkFile%, ""
  267.  
  268. '----------- SPECIFY THE NAME OF THE DEFINITIONS FILE -----------------
  269. PRINT #LnkFile%, "NUL.DEF ;"
  270.  
  271. PRINT #LnkFile%,
  272.  
  273. CLOSE #MkeFile%, #LnkFile%
  274.  
  275. PRINT "Makefile has been generated."
  276. PRINT "Type NMAKE "; MakeFile$; " to begin compilation."
  277. END
  278.  
  279. '--- these are the names of settings which can be set in the .INI file
  280. '**** change 'CONST NumSettings' if you add or delete any of these. ****
  281. SettingNames:
  282. DATA 1,Compile,         2,Link,         3,CompFlags
  283. DATA 4,LinkFlags,       5,Lib,          6,Replace
  284. DATA 7,CheckIncludes,   8,ObjDir
  285.  
  286. ' Billy Dennigan 2-Sep-1992
  287. '  Function to derive a qualifier from a string such as COMMAND$
  288. '  Eg: input CmdParam$("/B /X=12", "X=") will return "12"
  289. '  Case insensitive.
  290. FUNCTION CmdParam$ (Cmd$, Ident$)
  291.  
  292. First% = INSTR(UCASE$(Cmd$), UCASE$(Ident$))
  293. IF First% THEN
  294.   First% = First% + LEN(Ident$)
  295.   Last% = First% - 1
  296.  
  297.   'First% points to the first letter of the string
  298.   'now step forward until the end is reached
  299.   'the string is separated by either a / or a space
  300.   DO
  301.     Last% = Last% + 1
  302.     Ch$ = MID$(Cmd$, Last%, 1)
  303.   LOOP UNTIL Ch$ = " " OR Ch$ = "/" OR Last% > LEN(Cmd$)
  304.  
  305.   CmdParam$ = RTRIM$(MID$(Cmd$, First%, Last% - First%))
  306. ELSE
  307.   CmdParam$ = ""
  308. END IF
  309.  
  310. END FUNCTION
  311.  
  312. ' Num% identifies the type of value you're looking for
  313. 'Eg: Lib=, Compiler=,... etc
  314. '
  315. FUNCTION GetValue$ (Num%, Ini() AS IniRec)
  316. STATIC LastNum%, CurrentItem%
  317.  
  318. '---- reset the pointer ---
  319. IF Num% = 0 THEN
  320.   LastNum% = 0
  321.   EXIT FUNCTION
  322. END IF
  323.  
  324. ' If we're now looking for a different attribute, go back to the start
  325. ' of the list, otherwise continue searching from where we left off the
  326. ' last time.
  327. IF Num% <> LastNum% THEN CurrentItem% = 1
  328.  
  329. DO UNTIL CurrentItem% > MaxIniLines
  330.   CurrentNum% = Ini(CurrentItem%).Index
  331.   CurrentItem% = CurrentItem% + 1
  332.   IF CurrentNum% = Num% THEN
  333.     Value$ = Ini(CurrentItem% - 1).Value
  334.     EXIT DO
  335.   END IF
  336. LOOP
  337. LastNum% = Num%
  338.  
  339. '---------------------------------------------------------------------------
  340. ' if a line of the form 'Value=$(var)' is found, the environment is searched
  341. ' for 'var=NewVar'. This is the same as having 'Value=NewVar' in the .INI
  342. ' file.
  343. Macro% = INSTR(Value$, "$(")
  344. IF Macro% THEN
  345.   Macro$ = MID$(Value$, Macro% + 2)
  346.   RBracket% = INSTR(Macro$, ")")
  347.   IF RBracket% = 0 THEN RBracket% = LEN(Macro$) + 1
  348.   Macro$ = UCASE$(LEFT$(Macro$, RBracket% - 1))
  349.   EnvValue$ = ENVIRON$(Macro$)
  350.   IF LEN(EnvValue$) THEN Value$ = EnvValue$
  351. END IF
  352.  
  353. GetValue$ = LTRIM$(RTRIM$(Value$))
  354. END FUNCTION
  355.  
  356. ' called from Main program
  357. ' 'Filename$' is opened and searched for the work '$include, and all its
  358. ' filespecs are printed to OutFile%
  359. '
  360. SUB IncludeFiles (Filename$, OutFile%)
  361. OpenInc$ = "$INCLUDE: '"
  362. CloseInc$ = "'"
  363. LenInc% = LEN(OpenInc$)
  364.  
  365. IF LEN(DIR$(Filename$)) = 0 THEN EXIT SUB
  366. Infile% = FREEFILE
  367. OPEN Filename$ FOR INPUT SHARED AS #Infile%
  368. DO WHILE NOT EOF(Infile%)
  369.   LINE INPUT #Infile%, Current$
  370.   Current$ = UCASE$(LTRIM$(RTRIM$(Current$)))
  371.   '--- if it has an INCLUDE statement ---
  372.   StartInc% = INSTR(Current$, OpenInc$)
  373.   IF (StartInc% > 0) AND (StartInc% < 6) THEN
  374.     EndInc% = INSTR(StartInc% + LenInc%, Current$, CloseInc$)
  375.     IF EndInc% = 0 THEN EXIT DO
  376.     FileSpec$ = MID$(Current$, StartInc% + LenInc%, EndInc% - LenInc% - StartInc%)
  377.     PRINT #OutFile%, " "; FileSpec$; " ";
  378.   END IF
  379. LOOP
  380.  
  381. CLOSE #Infile%
  382. END SUB
  383.  
  384. 'CALLED FROM: Main Program
  385. '------ load in the list of required files from the .MAK file --------
  386. SUB LoadList (ListFile$, ObjList$(), NumObjs%)
  387.  
  388. IF LEN(DIR$(ListFile$)) THEN
  389.   LstFile% = FREEFILE
  390.   OPEN ListFile$ FOR INPUT AS #LstFile%
  391.   DO UNTIL EOF(LstFile%)
  392.     LINE INPUT #LstFile%, Line$
  393.     Line$ = UCASE$(Line$)
  394.     IF (LEN(Line$) = 0) THEN
  395.       EXIT DO
  396.     END IF
  397.     NumObjs% = NumObjs% + 1
  398.     ObjList$(NumObjs%) = Line$
  399.   LOOP
  400.   CLOSE #LstFile%
  401. ELSE
  402.   ' there is no .MAK file, just a single source file
  403.   NumObjs% = 1
  404.   ObjList$(NumObjs%) = RemoveExt$(ListFile$) + ".BAS"
  405. END IF
  406.  
  407. END SUB
  408.  
  409. 'read the settings from the .INI file
  410. '
  411. SUB ReadIni (IniFile$, Ini() AS IniRec)
  412.  
  413. DIM Setting$(NumSettings), SettingNum%(NumSettings)
  414. RESTORE SettingNames
  415. FOR i% = 1 TO NumSettings: READ SettingNum%(i%), Setting$(i%): NEXT i%
  416. NumLines% = 0
  417.  
  418. IniFile% = FREEFILE
  419. OPEN IniFile$ FOR INPUT SHARED AS #IniFile%
  420. DO WHILE NOT EOF(IniFile%)
  421.   LINE INPUT #IniFile%, IniLine$
  422.   IniLine$ = LTRIM$(RTRIM$(IniLine$))
  423.   DO   ' just once
  424.     ' ignore everything to t'right of a '#'
  425.     Hash% = INSTR(IniLine$, "#")
  426.     IF Hash% THEN
  427.       IniLine$ = LEFT$(IniLine$, Hash% - 1)
  428.     END IF
  429.  
  430.     Centre% = INSTR(IniLine$, "=")              'Eg: "LIB=C:\bc7\lib\im2.lib"
  431.     IF Centre% <= 1 THEN EXIT DO
  432.     Lhs$ = LCASE$(LEFT$(IniLine$, Centre% - 1))
  433.     Lhs$ = LTRIM$(RTRIM$(Lhs$))                 'Eg: "LIB"
  434.     Rhs$ = MID$(IniLine$, Centre% + 1)
  435.     Rhs$ = LTRIM$(RTRIM$(Rhs$))                 'Eg: "C:\bc7\lib\im2.lib"
  436.     ' now find the setting which matches the L.H.S and assign it the value of
  437.     ' the R.H.S.
  438.     Match% = 0
  439.     FOR i% = 1 TO NumSettings
  440.       IF LCASE$(Setting$(i%)) = Lhs$ THEN
  441.         Match% = SettingNum%(i%)
  442.         EXIT FOR
  443.       END IF
  444.     NEXT i%                                     ' Eg: Match% = 5
  445.     '--- match% is now an index for which setting to assign this RHS value
  446.     IF Match% THEN
  447.       NumLines% = NumLines% + 1
  448.       Ini(NumLines%).Index = Match%             ' Eg: 5
  449.       Ini(NumLines%).Value = Rhs$               ' Eg: "C:\bc7\lib\im2.lib"
  450.     END IF
  451.   LOOP UNTIL TRUE
  452. LOOP
  453. CLOSE #IniFile%
  454.  
  455. END SUB
  456.  
  457. ' Billy Dennigan  17-Jul-1992
  458. ' Function to strip the '.EXT' off a filename
  459. ' Eg:   Input:  "MENU.C"
  460. '       Output: "MENU"
  461. FUNCTION RemoveExt$ (Filename$)
  462.  
  463. 'step from Right to Left to avoid dots occurring in the path spec.
  464. TmpName$ = Filename$
  465. FOR Dot% = LEN(TmpName$) TO 1 STEP -1
  466.   Ch$ = MID$(TmpName$, Dot%, 1)
  467.   IF Ch$ = "." THEN EXIT FOR
  468.   IF Ch$ = "\" THEN Dot% = 0
  469. NEXT Dot%
  470.  
  471. IF Dot% > 0 THEN
  472.   TmpName$ = LEFT$(Filename$, Dot% - 1)
  473. END IF
  474. RemoveExt$ = TmpName$
  475.  
  476. END FUNCTION
  477.  
  478. 'Remove the path from a filename
  479. ' Eg:   Input:  "\PATH\MENU.C"
  480. '       Output: "MENU.C"
  481. FUNCTION RemovePath$ (Filename$)
  482.  
  483. 'step from Right to Left to avoid dots occurring in the path spec.
  484. TmpName$ = Filename$
  485.  
  486. FOR Slash% = LEN(TmpName$) TO 1 STEP -1
  487.   Ch$ = MID$(TmpName$, Slash%, 1)
  488.   IF Ch$ = "\" THEN EXIT FOR
  489. NEXT Slash%
  490.  
  491. IF Slash% > 0 THEN
  492.   TmpName$ = MID$(Filename$, Slash% + 1)
  493. END IF
  494. RemovePath$ = LTRIM$(RTRIM$(TmpName$))
  495.  
  496.  
  497. END FUNCTION
  498.  
  499. '
  500. '
  501. SUB ShowHelp ()
  502.  
  503. PRINT "USAGE: MM [filespec]"
  504. PRINT "           <filespec> contains a list of files used to make a target file."
  505. PRINT
  506. PRINT " Configuration file MM.INI should be in the current directory, if it"
  507. PRINT " is not, MM will prompt for the name of a configuration file."
  508. PRINT
  509. PRINT "Settings for the configuration file:"
  510. PRINT
  511. PRINT "  Compile = <filespec>   specifies your compiler."
  512. PRINT
  513. PRINT "  Link = <filespec>      specifies your linker."
  514. PRINT
  515. PRINT "  Lib = <filespec>[;]    specifies a library file. There can be as many"
  516. PRINT "                         Lib statements as you wish."
  517. PRINT "                         A semi-colon terminates the list of library"
  518. PRINT "                         specifications, otherwise MM will prompt the"
  519. PRINT "                         user for extra libraries."
  520. PRINT
  521. GOSUB HoldIt
  522. PRINT
  523. PRINT
  524. PRINT "  ObjDir = <dirspec>     This may be used to specify a directory where all"
  525. PRINT "                         object files are to be placed."
  526. PRINT
  527. PRINT "  CompFlags = <expression>       specifies switches used by the compiler."
  528. PRINT
  529. PRINT "  LinkFlags = <expression>       specifies switches used by the linker."
  530. PRINT
  531. PRINT "  Replace = OldString//NewString "
  532. PRINT "                         All occurrances of 'OldString' in filenames are"
  533. PRINT "                         replaced with 'NewString'. Use this for subtituting"
  534. PRINT "                         paths or filename extensions."
  535. PRINT
  536. PRINT "  Replace = OldString/NewString1[,NewString2[NewStringn[,... "
  537. PRINT "                         Occurrances of 'OldString' in filenames are"
  538. PRINT "                         replaced with 'NewString1'. If the resulting"
  539. PRINT "                         file is present, this will be written to the"
  540. PRINT "                         Makefile, otherwise 'NewString2' will be tried,"
  541. PRINT "                         and so until until a file is found."
  542. PRINT
  543. PRINT
  544. GOSUB HoldIt
  545. PRINT
  546. PRINT "  CheckIncludes = True|False     If this is set to True, each source file"
  547. PRINT "                                 is checked for INCLUDEd files, and any found"
  548. PRINT "                                 are put in the dependencies list."
  549. PRINT
  550. PRINT "     Expressions of the form  X=$(Y) cause the environment to be searched."
  551. PRINT "     For example Lib = $(LIBDIR) causes the environment to be searched for"
  552. PRINT "     an entry LIBDIR="
  553. PRINT "     So, if in you environment settings you have LIBDIR=C:\VBDOS\LIB ,this"
  554. PRINT "     is the same as having the line LIB=C:\VBDOS\LIB in the "
  555. PRINT "     MM.INI file."
  556. PRINT
  557. EXIT SUB
  558.  
  559. '------------- Pause after filling a screen --------
  560. HoldIt:
  561. COLOR 15, 0
  562. PRINT " Press any key to continue...."
  563. COLOR 7, 0
  564. DO: LOOP UNTIL LEN(INKEY$)
  565.  
  566. RETURN
  567.  
  568. END SUB
  569.  
  570. ' Want to replace .STB files with either .FRM or .BAS ,
  571. ' only one of the two is present.
  572. ' change$ is of the form OLD/NEW1,NEW2,...,NEWn
  573. ' NEW1 is searched for, if it is found then it is used to replace OLD, if
  574. ' not, NEW2 is searched for, then NEW3, .....
  575. ' If Change$ is of the form OLD//NEW (i.e. Two slashes), the replacement
  576. ' is performed regardless of whether the NEW file is found.
  577. '  Eg: xxxOLDyy would be replaced by xxxNEWyy
  578. ' ( The purpose of this is to automatically reinstate stub files in the
  579. '   environment when building an EXE file.)
  580. '
  581. SUB Substitute (Change$, ObjList$())
  582.  
  583. Slash% = INSTR(Change$, "/")
  584. IF Slash% <= 1 THEN EXIT SUB
  585.  
  586. OldStr$ = UCASE$(LEFT$(Change$, Slash% - 1))
  587. OldLen% = LEN(OldStr$)
  588. Rhs$ = UCASE$(MID$(Change$, Slash% + 1))
  589.  
  590. '--- check for a second slash, if one is there then we   ---
  591. '--- don't care whether the substitute file is present.  ---
  592. IF LEFT$(Rhs$, 1) = "/" THEN
  593.   DontCare% = TRUE
  594.   Rhs$ = MID$(Rhs$, 2)
  595. END IF
  596.  
  597. FOR i% = 1 TO NumOfSources
  598.   OldPos% = 0
  599.   LeftComma% = 1
  600.   RightComma% = 2
  601.   DO     ' once per substitute on the RHS until a valid substitute is found
  602.     CurrentFile$ = ObjList$(i%)
  603.     OldPos% = INSTR(CurrentFile$, OldStr$)
  604.     IF OldPos% = 0 THEN EXIT DO
  605.  
  606.     RightComma% = INSTR(LeftComma%, Rhs$, ",")
  607.     IF RightComma% = 0 THEN RightComma% = LEN(Rhs$) + 1
  608.     NewLen% = RightComma% - LeftComma%   ' length of one NEW string
  609.     IF NewLen% <= 0 THEN EXIT DO
  610.     NewStr$ = MID$(Rhs$, LeftComma%, NewLen%)
  611.     LeftComma% = RightComma% + 1
  612.  
  613.     ' construct the new line from parts of its old self and the new string
  614.     CurrentFile$ = LEFT$(CurrentFile$, OldPos% - 1) + NewStr$ + MID$(CurrentFile$, OldPos% + OldLen%)
  615.  
  616.     'if the replace file exists, put it into the makefile
  617.     IF LEN(DIR$(CurrentFile$)) OR DontCare% THEN
  618.       PRINT " Replacing "; ObjList$(i%), " with : "; CurrentFile$
  619.       ObjList$(i%) = CurrentFile$
  620.       EXIT DO
  621.     END IF    ' len(dir$(CurrentFile$))...
  622.   LOOP
  623. NEXT i%
  624.  
  625. END SUB
  626.  
  627.